####
#
# Copyright 2007 B. Chandler Carruth
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
####
#
# ./lib/rcons/files/source_file_target.rb
#
# This file provides the basic source file target functionality.
#
####

require( 'rcons/file_target' )
require( 'rcons/tools/compiler_target' )

module RCons

  # Provides abstract source file functionality.
  #
  # An example of a child class:  +CSourceFileTarget+.
  #
  # Extends +FileTarget+.
  class SourceFileTarget < FileTarget

    # Initializes a source file target.  Makes sure the file exists, and
    # creates a +FileTarget+ if +src+ is a path.  Validates the +compiler+,
    # and adds the compiler and source dependencies for the node.
    #
    # Inputs:
    #
    # +build_env+:: an +Environment+.
    # +src+:: the path to the source file, or a +FileTarget+.
    # +name+:: the name of the file target.
    # +compiler+:: a compiler to be used to compile the target.
    # +opts+:: a list of options.
    def initialize( build_env, src, name, compiler, opts = Hash.new() )
      # handle all the defaults for a target
      super( build_env, name, opts )

      # test to see if we got an explicit target, or a name
      if src.kind_of?( FileTarget )
        # just use the target we're given, allows special cases
        @src = src
        @src_name = @src.file_name
      else
        # treat it as a name, and automatically construct a target for
        # it
        @src_name = src.to_s()
        @src = FileTarget.new( @build_env, @src_name, opts )
      end
      @builder.src_name = @src_name

      # check for a compiler
      raise( ArgumentError,
        "Unexpected type for compiler argument.",
        caller() ) unless compiler.kind_of?( CompilerTarget )

      @compiler = compiler
      @builder.compiler = @compiler

      # add a dependency for the source file
      add_pre_dep( @compiler )
      add_pre_dep( @src )
    end

    # The SourceFileTarget overriden Builder class.
    class Builder < superclass()::Builder
      attr_accessor( :src_name, :compiler )

      # This is the custom method for building this type of target
      def do_build( has_changed )
        if has_changed or not File.exists?( @build_env.expand( @file_name ) )
          return false unless @compiler.compile( @file_name, @src_name )
          super( true )
        else
          super( false )
        end
      end
    end
  end
end

